package com.nbot.server.job;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.nbot.common.command.s2b.ReportCctvCommand;
import com.nbot.server.BotServer;
import com.nbot.server.domain.CctvDO;
import com.nbot.server.domain.ChecklogDO;
import com.nbot.server.service.CctvService;
import com.nbot.server.service.ChecklogService;
import com.nbot.server.util.NetworkUtil;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 摄像头连通性监控任务
 */
@Component
public class CctvJob implements Job {
    private static final Log LOGGER = LogFactory.get();

    @Autowired
    private CctvService cctvService;

    @Autowired
    private BotServer botServer;

    @Autowired
    private ChecklogService checklogService;


    /**
     * 判断摄像头是否存活
     * 连续pingTimes次ping（超时时间为3秒）不通，则认为摄像头不存活
     *
     * @param cctvDO
     * @param pingTimes
     * @return
     */
    private static boolean isLive(CctvDO cctvDO, int pingTimes) {
        boolean reslut = false;
        for (int i = 0; i < pingTimes; i++) {
            if (NetworkUtil.getInstance().isReachIp(cctvDO.getIp())) {
                reslut = true;
                break;
            }
        }
        return reslut;
    }

    /**
     * 判断摄像头是否存活
     * 连续20次ping（超时时间为3秒）不通，则认为摄像头不存活
     *
     * @param cctvDO
     * @return
     */
    private static boolean isLive(CctvDO cctvDO) {
        return isLive(cctvDO, 20);
    }

    /**
     * 摄像头不存活的时候的处理步骤
     *
     * @param cctvDO
     */
    private void baoJingChuLi(CctvDO cctvDO) {
        ReportCctvCommand reportCctvCommand = null;
        String alarmType = null;
        if (cctvDO.getAutoId()>1000){
            reportCctvCommand = new ReportCctvCommand();
            reportCctvCommand.setDesc(cctvDO.getWarnDesc() + "！");
            reportCctvCommand.setIp(cctvDO.getIp());
            reportCctvCommand.setPinged(false);
            alarmType = "RTU通讯";
        }else {
            reportCctvCommand = new ReportCctvCommand();
            reportCctvCommand.setDesc(cctvDO.getWarnDesc() + "信号中断！");
            reportCctvCommand.setIp(cctvDO.getIp());
            reportCctvCommand.setPinged(true);
            alarmType = "网络信号";
        }
        Calendar beforeTime = Calendar.getInstance();
        beforeTime.add(Calendar.MINUTE, -Integer.parseInt("120"));//计算n分钟前的date对象
        Date beforeD = beforeTime.getTime();
        List<ChecklogDO> logs = null;
        String disp = reportCctvCommand.getDesc();
        logs = checklogService.logInNminsBydisp(disp, alarmType, beforeD.getTime() / 1000);

        //将当前报警值进行保存
        //如果10分钟内没有相同，则发送报警指令
        if (logs.isEmpty()) {
            ChecklogDO checklog = new ChecklogDO();

            try {
                BotServer.addUartMsg(reportCctvCommand);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            checklog.setTag(cctvDO.getDescription());
            checklog.setDispdesc(disp);
            checklog.setChecktimestamp(new Date());
            checklog.setCheckvalue(alarmType);
            checklog.setTruthvalue(cctvDO.getIp());
            checklog.setAlarmlevel("重要");
            checklog.setBackup("TX");
            checklogService.insert(checklog);
        }
    }

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        LOGGER.info("执行摄像头连通性监控任务");
        List<CctvDO> list = cctvService.list(null);
        if (list == null) {
            return;
        }
        if (list.isEmpty()) {
            return;
        }
        for (CctvDO cctvDO : list) {
            ThreadUtil.execute(new Runnable() {
                @Override
                public void run() {
                    if (!isLive(cctvDO)) {
                        baoJingChuLi(cctvDO);
                    }
                }
            });
        }
    }

}